/*	$Id: uritest.c 983 2009-09-01 02:45:42Z phrakt $	*/
/*
 * Copyright (c) 2008 Jean-Francois Brousseau <phrakt@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Sample URIs that should be parsable:
 *
 *	http://www.example.com/
 *	http://index.html
 *	http://user@www.example.com/
 *	http://user:pwd@www.example.com/
 *	http://www.example.com/somepath/index.html
 *	http://www.example.com:8080/somepath/index.html
 *	http://www.example.com/index.pl?queryarg1=foo&queryarg2=bar
 *	http://index.html#myfragment
 *	/index.html
 *	/my/path/to/script?qarg=foo&oarg=bar
 */

#include <sys/types.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <canopy/log.h>

#include <http/http.h>
#include <http/uri.h>

#include "test.h"



struct uri_desc {
	const char   *uri_full;
	const char   *uri_scheme;
	const char   *uri_host;
	const char   *uri_path;
	const char   *uri_query;
	const char   *uri_fragment;
};




struct uri_desc tests[] = {
	{
		"http://example.com",
		"http", "example.com", "/", NULL, NULL
	},
	{
		"http://example.com/",
		"http", "example.com", "/", NULL, NULL
	},
	{
		"http://www.example.com/index.html",
		"http", "www.example.com", "/index.html", NULL, NULL
	},
	{
		"http://terraquati.ca/dir/ect/ory/index.html",
		"http", "terraquati.ca", "/dir/ect/ory/index.html", NULL, NULL
	},
	{
		"/somefile.html",
		"", NULL, "/somefile.html", NULL, NULL,
	},
	{
		"http://example.com/cgi-bin/script?arg1=blah&arg2=bleh",
		"http", "example.com", "/cgi-bin/script", "arg1=blah&arg2=bleh",
		NULL
	},
	{
		"http://example.com/file.html#fragment",
		"http", "example.com", "/file.html", NULL, "fragment",
	},
	{
		"https://example.com/login",
		"https", "example.com", "/login", NULL, NULL,
	},
	{
		"ftp://example.com/pub/Idiotic File Name.doc",
		"ftp", "example.com", "/pub/Idiotic%20File%20Name.doc", NULL,
		NULL,
	},
};


int
test_parse_uri(struct uri_desc *desc)
{
	http_uri_t *uri;
	const char *val;

	test_log("Testing parsing of %s", desc->uri_full);

	if ((uri = http_uri_parse(desc->uri_full)) == NULL) {
		return (TEST_FAIL);
	}

	val = http_uri_getscheme(uri);
	TEST_ASSERT_STRINGS_EQUAL("scheme", desc->uri_scheme, val);

	val = http_uri_gethost(uri);
	TEST_ASSERT_STRINGS_EQUAL("host", desc->uri_host, val);

	val = http_uri_getpath(uri);
	TEST_ASSERT_STRINGS_EQUAL("path", desc->uri_path, val);

	val = http_uri_getquery(uri);
	TEST_ASSERT_STRINGS_EQUAL("query", desc->uri_query, val);

	val = http_uri_getfragment(uri);
	TEST_ASSERT_STRINGS_EQUAL("fragment", desc->uri_fragment, val);

	return (TEST_OK);
}


int
test_format_uri(struct uri_desc *desc)
{
	char uribuf[1024];
	http_uri_t *uri;

	test_log("Testing formatting of %s", desc->uri_full);

	if ((uri = http_uri_alloc()) == NULL) {
		test_log("Allocation failed");
		return (TEST_FAIL);
	}

	if (http_uri_setscheme(uri, desc->uri_scheme) == -1) {
		test_log("Failed to set scheme");
		return (TEST_FAIL);
	}

	if (http_uri_sethost(uri, desc->uri_host) == -1) {
		test_log("Failed to set host");
		return (TEST_FAIL);
	}

	if (http_uri_setpath(uri, desc->uri_path) == -1) {
		test_log("Failed to set path");
		return (TEST_FAIL);
	}

	if (http_uri_setquery(uri, desc->uri_query) == -1) {
		test_log("Failed to set query");
		return (TEST_FAIL);
	}

	if (http_uri_setfragment(uri, desc->uri_fragment) == -1) {
		test_log("Failed to set fragment");
		return (TEST_FAIL);
	}

	http_uri_format(uri, uribuf, sizeof(uribuf), 0);

	if (strcmp(uribuf, desc->uri_full) != 0) {
		test_log("URIs do not match (%s, %s)", uribuf, desc->uri_full);
		return (TEST_FAIL);
	}

	return (TEST_OK);
}


int
main(int argc, char **argv)
{
	int result;
	unsigned int i;

	http_init();
	test_init();

	for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) {
		test_start("test_parse_uri");
		result = test_parse_uri(&tests[i]);
		test_end(result);
	}

	for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); i++) {
		test_start("test_format_uri");
		result = test_format_uri(&tests[i]);
		test_end(result);
	}

	test_cleanup();

	return (0);
}
